package com.codeest.geeknews.util.okhttp;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;

import com.codeest.geeknews.component.OkhttpDownloadService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Singleton;

/**
 * Created by admin on 2017/7/19.
 */
public class OkhttpDownloadServiceUtils {

    private List<OkhttpDownloadService.OnProgressListener> onProgressListeners = new ArrayList<>();
    private final static String TAG = "DownloadServiceUtils";
    private OkhttpDownloadService sService = null;
    private HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
    private static OkhttpDownloadServiceUtils singleton;

    public static OkhttpDownloadServiceUtils getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new OkhttpDownloadServiceUtils();
                }
            }
        }
        return singleton;
    }

    public static void insert(Context context, String uri) {

    }


    public static class ServiceToken {
        ContextWrapper mWrappedContext;

        ServiceToken(ContextWrapper context) {
            mWrappedContext = context;
        }
    }

    public /*static*/ ServiceToken bindToService(Activity context) {
        return bindToService(context, null);
    }

    public /*static*/ ServiceToken bindToService(Activity context, ServiceConnection callback) {
        Activity realActivity = context.getParent();
        if (realActivity == null) {
            realActivity = context;
        }
        ContextWrapper cw = new ContextWrapper(realActivity);
        cw.startService(new Intent(cw, OkhttpDownloadService.class));
        ServiceBinder sb = new ServiceBinder(callback);
        if (cw.bindService((new Intent()).setClass(cw, OkhttpDownloadService.class), sb, 0)) {
            sConnectionMap.put(cw, sb);
            return new ServiceToken(cw);
        }
        Log.e(TAG, "Failed to bind to service");
        return null;
    }

    public /*static*/ void unbindFromService(ServiceToken token) {
        if (token == null) {
            Log.e(TAG, "Trying to unbind with null token");
            return;
        }
        ContextWrapper cw = token.mWrappedContext;
        ServiceBinder sb = sConnectionMap.remove(cw);
        if (sb == null) {
            Log.e(TAG, "Trying to unbind for unknown Context");
            return;
        }
        cw.unbindService(sb);
        if (sConnectionMap.isEmpty()) {
            // presumably there is nobody interested in the service at this point,
            // so don't hang on to the ServiceConnection
            sService = null;
        }
    }

    /**
     * 对外开发的方法
     *
     * @param onProgressListener-
     */
    public void addOnProgressListener(OkhttpDownloadService.OnProgressListener onProgressListener) {
        onProgressListeners.add(onProgressListener);
    }

    public void removeOnProgressListener(OkhttpDownloadService.OnProgressListener onProgressListener) {
        onProgressListeners.remove(onProgressListener);
    }

    public void startDownload(String url) {
        if (sService == null) {
            throw new IllegalStateException("未绑定服务:OkhttpDownloadService");
        }
        sService.startDownload(url);
    }

    private static int bindCount = 0;

    private /*static*/ class ServiceBinder implements ServiceConnection {
        ServiceConnection mCallback;


        ServiceBinder(ServiceConnection callback) {
            mCallback = callback;
        }

        public void onServiceConnected(ComponentName className, android.os.IBinder service) {
            if (bindCount == 0) {//第一次绑定的时候才设置监听(避免重复添加监听类，或者将service的addOnProgressListener改为Set存储)
                OkhttpDownloadService.DownloadBinder binder = (OkhttpDownloadService.DownloadBinder) service;
                sService = binder.getService();
                sService.addOnProgressListener(onProgressListener);
            }
            if (mCallback != null) {
                mCallback.onServiceConnected(className, service);
            }
            bindCount++;
        }

        public void onServiceDisconnected(ComponentName className) {
            bindCount--;
            if (bindCount == 0) {
                sService.removeOnProgressListener(onProgressListener);
            }
            if (mCallback != null) {
                mCallback.onServiceDisconnected(className);
            }
            //sService = null;
        }
    }

    public List<DownloadInfo> getDownloads() {
        if (sService == null) {
            throw new IllegalStateException("未绑定服务:OkhttpDownloadService");
        }
        List<DownloadInfo> downloadInfoList = new ArrayList<>();
        LinkedHashMap<String, DownloadInfo> downloads = sService.getDownloads();
        for (Map.Entry<String, DownloadInfo> entry : downloads.entrySet()) {
            downloadInfoList.add(entry.getValue());
        }
        return downloadInfoList;
    }

    public int getDownloadCount() {
        if (sService == null) {
            new IllegalStateException("未绑定服务:OkhttpDownloadService").printStackTrace();
            return 0;
        }
        return sService.getDownloads().size();
    }

    private OkhttpDownloadService.OnProgressListener onProgressListener = new OkhttpDownloadService.OnProgressListener() {
        @Override
        public void onProgress(float fraction, DownloadInfo downloadInfo) {
            for (OkhttpDownloadService.OnProgressListener onProgressListener : onProgressListeners) {
                onProgressListener.onProgress(fraction, downloadInfo);
            }
        }

        @Override
        public void onComplete(DownloadInfo downloadInfo) {
            for (OkhttpDownloadService.OnProgressListener onProgressListener : onProgressListeners) {
                onProgressListener.onComplete(downloadInfo);
            }
        }
    };

}
